/*
 * @Author: Clark
 * @Email: haixuanwoTxh@gmail.com
 * @Date: 2023-01-18 21:04:03
 * @LastEditors: Clark
 * @LastEditTime: 2023-01-18 21:09:26
 * @Description: file content
 */

#include <stdlib.h>
#include <pthread.h>

struct foo {
    int             f_count;
    pthread_mutex_t f_lock;
    int             f_id;
    // ... more stuff here ...
};

struct foo *foo_alloc(int id)   // allocate the object
{
    struct foo *fp = malloc(sizeof(struct foo));
    if (NULL == fp)
    {
        return NULL;
    }

    fp->f_count = 1;
    fp->f_id = id;

    if (pthread_mutex_init(&fp->f_lock, NULL) != 0)
    {
        free(fp);
        return NULL;
    }
    // ... continue initialization ...

    return fp;
}

void foo_hold(struct foo *fp) // add a reference to the object
{
    pthread_mutex_lock(&fp->f_lock);
    fp->f_count++;
    pthread_mutex_unlock(&fp->f_lock);
}

void foo_rele(struct foo *fp) // release a reference to the object
{
    pthread_mutext_lock(&fp->f_lock);
    if (--fp->f_count == 0) // last reference
    {
        pthread_mutex_unlock(&fp->f_lock);
        pthread_mutex_destroy(&fp->f_lock);
        free(fp);
    }    
    else
    {
        pthread_mutex_unlock(&fp->f_lock);
    }
}
